//---------------------------------------------------------------------
// File: EventLogger.cs
// 
// Summary: Logs messages to the event log
//
//
//---------------------------------------------------------------------
// This file is part of the Microsoft ESB Guidance for BizTalk
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// This source code is intended only as a supplement to Microsoft BizTalk
// Server 2006 R2 release and/or on-line documentation. See these other
// materials for detailed information regarding Microsoft code samples.
//
// THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
// KIND, WHETHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
// PURPOSE.
//---------------------------------------------------------------------
using System.Reflection;
using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using System.Globalization;
using System.Security.Permissions;

namespace Microsoft.Practices.ESB.Exception.Management
{
    /// <summary>
    /// This class has the functions responsible for logging a message
    /// to the event log and writing trace statements
    /// </summary>
    public static class EventLogger
    {
        /// <summary>
        /// Used by other methods callig LogMessage. Use to indicate 
        /// the event Id to post to event log.  Event IDs are used
        /// to represent various sub systems of the solution
        /// </summary>
        public enum EventId { None = 0, 
            Default = 5000, 
            ExceptionPipeline = 5010, 
            ExceptionBAMPipeline = 5020,
            ExceptionCore = 5030,
            DispatcherPipeline = 5040,
            DispatcherDisassemblePipeline = 5050,
            TransformPipeline = 5060,
            TransformDisassemblePipeline = 5070,
            AddNamespacePipeline = 5080,
            RemoveNamespacePipeline = 5090,
            Transform = 6000,
            BizTalkQuery = 6010,
            BizTalkQueryService = 6020,
            Uddi = 6030,
            UddiService = 6040,
            TransformService = 6050,
            Resolver = 6060,
            ResolverService = 6070,
            ItineraryPipeline = 6080,
            Itinerary = 6090,
            AdapterManager = 7000
        };

        /// <summary>
        /// Writes formatted message to System.Diagnostics.Trace.Write if DEBUG = true.
        /// </summary>
        /// <param name="message">Custom message</param>
        /// <param name="exception">System.Exception object</param>
        public static void Write(string message, System.Exception exception)
        {
            if (string.IsNullOrEmpty(message))
                throw new ArgumentNullException("message");
            if (null == exception)
                throw new ArgumentNullException("exception");

            #if DEBUG
            System.Diagnostics.Trace.Write(String.Format(CultureInfo.CurrentCulture,"{0}. Exception message: {1} Exception Source {2}",message,exception.Message,exception.Source));
            #endif
        }
        /// <summary>
        /// Writes formatted message to System.Diagnostics.Trace.Write if DEBUG = true.
        /// </summary>
        /// <param name="message">Custom message</param>
        /// <param name="memberInfo">MemberInfo object for method information</param>
        /// <param name="exception">System.Exception object</param>
        public static void Write(string message, MemberInfo memberInfo, System.Exception exception)
        {
            if (string.IsNullOrEmpty(message))
                throw new ArgumentNullException("message");
            if (null == memberInfo)
                throw new ArgumentNullException("memberInfo");
            if (null == exception)
                throw new ArgumentNullException("exception");

            #if DEBUG
            string messageWrite = EventFormatter.FormatError(MethodInfo.GetCurrentMethod(), EventFormatter.ErrorFormat.Message, exception.Message.ToString(), exception.Source);
            System.Diagnostics.Trace.Write(message + " : " + messageWrite);
            #endif
        }
        /// <summary>
        /// Writes formatted message to System.Diagnostics.Trace.Write if DEBUG = true.
        /// </summary>
        /// <param name="memberInfo">MemberInfo object for method information</param>
        /// <param name="exception">System.Exception object</param>
        public static void Write(MemberInfo memberInfo, System.Exception exception)
        {
            if (null == memberInfo)
                throw new ArgumentNullException("memberInfo");
            if (null == exception)
                throw new ArgumentNullException("exception");

            #if DEBUG
            string messageWrite = EventFormatter.FormatError(memberInfo, EventFormatter.ErrorFormat.Message, exception.Message.ToString(), exception.Source);
            System.Diagnostics.Trace.Write(messageWrite);
            #endif
        }
        /// <summary>
        /// Writes formatted message to System.Diagnostics.Trace.Write if DEBUG = true.
        /// </summary>
        /// <param name="message">Custom message</param>
        /// <param name="memberInfo">MemberInfo object for method information</param>
        public static void Write(string message, MemberInfo memberInfo)
        {
            if (string.IsNullOrEmpty(message))
                throw new ArgumentNullException("message");
            if (null == memberInfo)
                throw new ArgumentNullException("memberInfo");

            #if DEBUG
            string messageWrite = EventFormatter.FormatError(MethodInfo.GetCurrentMethod(), EventFormatter.ErrorFormat.Message, "", "");
            System.Diagnostics.Trace.Write(message + " : " + messageWrite);
            #endif

        }
        /// <summary>
        /// Writes formatted message to System.Diagnostics.Trace.Write if DEBUG = true.
        /// </summary>
        /// <param name="message">Custom message</param>
        public static void Write(string message)
        {
            if (string.IsNullOrEmpty(message))
                throw new ArgumentNullException("message");

            // Write to trace if flag is set
            #if DEBUG
            System.Diagnostics.Trace.Write(message);
            #endif
        }
        /// <summary>
        /// Writes formatted message to System.Diagnostics.Trace.Write if DEBUG = true.
        /// </summary>
        /// <param name="memberInfo">MemberInfo object for method information</param>
        public static void Write(MemberInfo memberInfo)
        {
            if (null == memberInfo)
                throw new ArgumentNullException("memberInfo");

            #if DEBUG
            string messageWrite = EventFormatter.FormatError(MethodInfo.GetCurrentMethod(), EventFormatter.ErrorFormat.Message, "", "");
            System.Diagnostics.Trace.Write(messageWrite);
            #endif
        }
        /// <summary>
        /// This posts a message to the event log.  The source and log are 
        /// predetermined by the BizTalkEventLogInstaller class, which 
        /// houses the Event Source installer.  If the source does not
        /// exist, then an attempt is made to run the Event Source installer
        /// </summary>
        /// <param name="message">Message to post to event log</param>
        /// <param name="eventlogEntryType">EventLogEntryType type. Indicates, Success, warning, information, or error</param>
        /// <param name="eventId">from the enum, EventId. Corresponds to Event Id in Event log</param>
        [EventLogPermission(SecurityAction.Demand,
            MachineName = ".",
           PermissionAccess = EventLogPermissionAccess.Write)]
        public static void LogMessage(string message, EventLogEntryType eventlogEntryType, 
            int eventId)
        {
            if (string.IsNullOrEmpty(message))
                throw new ArgumentNullException("message");

            EventLog myEventLog = null;
            BizTalkEventLogInstaller bizTalkEventLogInstaller = null;

            // default event id
            if (eventId == 0) {eventId = (int)EventId.Default;}

            try
            {
                // Create the event source if it does not exist.
                if (!EventLog.SourceExists(BizTalkEventLog.Source))
                {
                    // Call a local method to register the event log source
                    // Use the resource file
                    // EventLogMsgs.dll in the current directory for message text.
                    string messageFile = String.Format(CultureInfo.CurrentCulture,"{0}\\{1}",
                        System.Environment.CurrentDirectory,
                        "EventLogMsgs.dll");
                    bizTalkEventLogInstaller = new BizTalkEventLogInstaller
                        (BizTalkEventLog.Source, BizTalkEventLog.Log, messageFile);
                    bizTalkEventLogInstaller = null;
                }

                // Get the event log corresponding to the existing source.
                string myLogName = EventLog.LogNameFromSourceName(BizTalkEventLog.Source, ".");

                myEventLog = new EventLog(myLogName, ".", BizTalkEventLog.Source);

                // Write to trace if flag is set
                #if DEBUG
                System.Diagnostics.Trace.Write(message);
                #endif

                // write event log
                myEventLog.WriteEntry(message, eventlogEntryType, eventId);
            }
            catch (System.Exception)
            {
                // just throw it
                throw;
            }
            finally
            {
                if (null != myEventLog)
                    myEventLog.Dispose();
                if (null != bizTalkEventLogInstaller)
                    bizTalkEventLogInstaller.Dispose();
            }
        }
    }
}
